/*----------------------------------------------------------------------------
Owner(s): Shane Whitfield
$Copyright: $
$Id: 

Purpose  : Holds on to all touch information for this frame
----------------------------------------------------------------------------*/

#pragma once

#include "singleton.h"
#include "subsystem.h"
#include "bbmath.h"

enum ETouchType
{
	BEGIN_ENUM(ETouchType_),
	
	ETouchType_SingleTouchStart,
	ETouchType_SingleTouchMoved,
    ETouchType_SingleTouchEnd,
	ETouchType_DoubleTapStart,
	ETouchType_TouchCancelled,
	ETouchType_DoubleTouchStart,
	ETouchType_DoubleTouchMoving,
	
	END_ENUM(ETouchType_)
};

/*--------------------------------------------------------------------------*/
// Class CTouchMgr declaration.
class CTouchMgr : public TSingleton<CTouchMgr>, public CSubsystem
{
	typedef CSubsystem super;

public:
					CTouchMgr();

	//subsystem overrides
	virtual void	OnPreWorldUpdate();
	virtual void	OnPostWorldLoad();
	virtual void	OnPostWorldUpdate();
	virtual void	OnPreIntroUpdate();
	virtual void	OnPostIntroUpdate();
	virtual void	OnPreMapUpdate();
	virtual void	OnPostMapUpdate();
	
	void			RegisterPendingTouch(ETouchType i_touchType, const Vector2f& i_screenPos, int i_numTaps, Vector2f* i_screenPos2 = NULL);
	bool			HasTouchEvent(ETouchType i_touchType, bool shouldAbsorb = true) const;
	void			ConsumeTouchEvent(ETouchType i_touchType) {
						m_hasFrameTouchEvent[i_touchType] = false; }
	bool			HasContact() const {
						return m_state != EState_NoTouch; }
	const Vector2f&	GetTouchEventScreenPos(ETouchType i_touchType) const {
						return m_touchEventScreenPos[i_touchType]; }
	Vector2f		GetTouchEventWorldPos(ETouchType i_touchType) const;
	const Vector2f&	GetTouchEventScreenPos2(ETouchType i_touchType) const {
						return m_touchEventScreenPos2[i_touchType]; }
	Vector2f		GetTouchEventWorldPos2(ETouchType i_touchType) const;
	float			GetContactDuration() const;
	float			GetCameraStillDuration() const;

	
private:

	enum EState
	{
		EState_NoTouch,
		
		EState_TouchStart,
		EState_Touching,
		EState_TouchingEnding
	};
	
	void		clearTouchEvents();
	void		clearTouchPos();
	void		pendingToCurrent();
	void		setState(EState i_state);
	void		update();
	
	float			m_tContactStarted;								// the time stamp of the current contact.
	EState			m_state;										// the current state of the contact
	bool			m_pendingHasFrameTouchEvent[ETouchType_Count];	// this is cleared every frame
	Vector2f		m_pendingTouchEventScreenPos[ETouchType_Count];
	Vector2f		m_pendingTouchEventScreenPos2[ETouchType_Count];
	mutable bool	m_hasFrameTouchEvent[ETouchType_Count];			// this is cleared every frame
	Vector2f		m_touchEventScreenPos[ETouchType_Count];			// this isn't cleared in order to get past information
	Vector2f		m_touchEventScreenPos2[ETouchType_Count];		// this isn't cleared in order to get past information
};
inline CTouchMgr& CTouchMgr_GetSingleton() { return CTouchMgr::GetSingleton(); }
#define g_touchmgr (CTouchMgr_GetSingleton())

/*-----------------------------------EOF!-----------------------------------*/